<!--
  ~ Licensed to the Apache Software Foundation (ASF) under one
  ~ or more contributor license agreements.  See the NOTICE file
  ~ distributed with this work for additional information
  ~ regarding copyright ownership.  The ASF licenses this file
  ~ to you under the Apache License, Version 2.0 (the
  ~ "License"); you may not use this file except in compliance
  ~ with the License.  You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<nz-tabset *ngIf="checkPointStats" [nzTabBarGutter]="4" [nzSize]="'small'" [nzAnimated]="{inkBar:true, tabPane:false}" [nzTabBarExtraContent]="extraTemplate">
  <nz-tab nzTitle="Overview">
    <nz-table
      class="no-border small"
      [nzData]="checkPointStats['latest'] ? ['']:[]"
      [nzSize]="'small'"
      [nzFrontPagination]="false"
      [nzShowPagination]="false">
      <tbody>
        <ng-container *ngIf="checkPointStats['latest'] && checkPointStats['counts']">
          <tr>
            <td><strong>Checkpoint Counts</strong></td>
            <td>
              <span><strong>Triggered: </strong> {{ checkPointStats['counts']['total'] }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong>In Progress: </strong> {{ checkPointStats['counts']['in_progress'] }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong>Completed: </strong> {{ checkPointStats['counts']['completed'] }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong>Failed: </strong> {{ checkPointStats['counts']['failed'] }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong>Restored: </strong> {{ checkPointStats['counts']['restored'] }}</span>
            </td>
          </tr>
          <tr>
            <td><strong>Latest Completed Checkpoint</strong></td>
            <td *ngIf="checkPointStats['latest']['completed']">
              <span><strong>ID: </strong> {{ checkPointStats['latest']['completed']['id'] }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong>Completion Time: </strong> {{ checkPointStats['latest']['completed']['latest_ack_timestamp'] | date:'yyyy-MM-dd HH:mm:ss' }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong>End to End Duration: </strong> {{ checkPointStats['latest']['completed']['end_to_end_duration'] | humanizeDuration}}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong>Checkpointed Data Size: </strong> {{ checkPointStats['latest']['completed']['state_size'] | humanizeBytes }}</span>
            </td>
            <td *ngIf="!checkPointStats['latest']['completed']">None</td>
          </tr>
          <tr *ngIf="checkPointStats['latest']['completed']">
            <td colspan="2" class="collapse-td">
              <flink-job-checkpoints-detail [checkPoint]="checkPointStats['latest']['completed']"></flink-job-checkpoints-detail>
            </td>
          </tr>
          <tr>
            <td><strong>Latest Failed Checkpoint</strong></td>
            <td *ngIf="checkPointStats['latest']['failed']">
              <span><strong>ID: </strong> {{ checkPointStats['latest']['failed']['id'] }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong>Failure Time: </strong> {{ checkPointStats['latest']['failed']['failure_timestamp'] | date:'yyyy-MM-dd HH:mm:ss' }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong *ngIf="checkPointStats['latest']['failed']['failure_message']">Cause: </strong> {{ checkPointStats['latest']['failed']['failure_message'] }}</span>
              <span *ngIf="!checkPointStats['latest']['failed']['failure_message']"><strong>Cause:</strong> n/a</span>
            </td>
            <td *ngIf="!checkPointStats['latest']['failed']">None</td>
          </tr>
          <tr *ngIf="checkPointStats['latest']['failed']">
            <td colspan="2" class="collapse-td">
              <flink-job-checkpoints-detail [checkPoint]="checkPointStats['latest']['failed']"></flink-job-checkpoints-detail>
            </td>
          </tr>
          <tr>
            <td><strong>Latest Savepoint</strong></td>
            <td *ngIf="checkPointStats['latest']['savepoint']">
              <span><strong>ID: </strong> {{ checkPointStats['latest']['savepoint']['id'] }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong>Completion Time: </strong> {{ checkPointStats['latest']['savepoint']['latest_ack_timestamp'] | date:'yyyy-MM-dd HH:mm:ss' }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong>Checkpointed Data Size: </strong> {{ checkPointStats['latest']['savepoint']['state_size'] | humanizeBytes }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong>Path: </strong> {{ checkPointStats['latest']['savepoint']['external_path'] }}</span>
            </td>
            <td *ngIf="!checkPointStats['latest']['savepoint']">None</td>
          </tr>
          <tr *ngIf="checkPointStats['latest']['savepoint']">
            <td colspan="2" class="collapse-td">
              <flink-job-checkpoints-detail [checkPoint]="checkPointStats['latest']['savepoint']"></flink-job-checkpoints-detail>
            </td>
          </tr>
          <tr>
            <td><strong>Latest Restore</strong></td>
            <td *ngIf="checkPointStats['latest']['restored']">
              <span><strong>ID: </strong> {{ checkPointStats['latest']['restored']['id'] }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong>Restore Time: </strong> {{ checkPointStats['latest']['restored']['restore_timestamp'] | date:'yyyy-MM-dd HH:mm:ss' }}</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span *ngIf="checkPointStats['latest']['restored']['is_savepoint']"><strong>Type:</strong> Savepoint</span>
              <span *ngIf="!checkPointStats['latest']['restored']['is_savepoint']"><strong>Type:</strong> Checkpoint</span>
              <nz-divider nzType="vertical"></nz-divider>
              <span><strong *ngIf="checkPointStats['latest']['restored']['external_path']">Path: </strong> {{ checkPointStats['latest']['restored']['external_path'] }}</span>
            </td>
            <td *ngIf="!checkPointStats['latest']['restored']">None</td>
          </tr>
        </ng-container>
      </tbody>
    </nz-table>
  </nz-tab>
  <nz-tab nzTitle="History">
    <nz-table
      class="no-border small"
      [nzSize]="'small'"
      [nzData]="checkPointStats['history'] || []"
      [nzFrontPagination]="false"
      [nzShowPagination]="false">
      <thead>
        <tr>
          <th nzShowExpand></th>
          <th><strong>ID</strong></th>
          <th><strong>Status</strong></th>
          <th><strong>Acknowledged</strong></th>
          <th><strong>Trigger Time</strong></th>
          <th><strong>Latest Acknowledgement</strong></th>
          <th><strong>End to End Duration</strong></th>
          <th><strong>Checkpointed Data Size</strong></th>
          <th><strong>Processed (persisted) in-flight data</strong></th>
        </tr>
      </thead>
      <tbody>
        <ng-container *ngFor="let checkpoint of checkPointStats['history']; trackBy:trackHistoryBy;">
          <tr>
            <td nzShowExpand [(nzExpand)]="checkpoint.expand"></td>
            <td>{{ checkpoint['id'] }}</td>
            <td>
              <flink-checkpoint-badge [state]="checkpoint['status']">
                {{ checkpoint['status'] }}
                <em *ngIf="checkpoint['is_savepoint']">[Savepoint]</em>
              </flink-checkpoint-badge>
            <td>
              {{ checkpoint['num_acknowledged_subtasks'] }}/{{ checkpoint['num_subtasks'] }}
              <span *ngIf="checkpoint['status'] == 'IN_PROGRESS'">({{ (checkpoint['num_acknowledged_subtasks']/checkpoint['num_subtasks']) | percent }})</span>
            </td>
            <td>{{ checkpoint['trigger_timestamp'] | date:'yyyy-MM-dd HH:mm:ss' }}</td>
            <td *ngIf="checkpoint['latest_ack_timestamp'] >= 0">{{ checkpoint['latest_ack_timestamp'] | date:'yyyy-MM-dd HH:mm:ss' }}</td>
            <td *ngIf="checkpoint['latest_ack_timestamp'] < 0">n/a</td>
            <td *ngIf="checkpoint['end_to_end_duration'] >= 0">{{ checkpoint['end_to_end_duration'] | humanizeDuration}}</td>
            <td *ngIf="checkpoint['end_to_end_duration'] <0">n/a</td>
            <td>{{ checkpoint['state_size'] | humanizeBytes }}</td>
            <td>{{ checkpoint['processed_data'] | humanizeBytes }} ({{ checkpoint['persisted_data'] | humanizeBytes }})</td>
          </tr>
          <tr [nzExpand]="checkpoint.expand">
            <td colspan="11" *ngIf="checkpoint.expand" class="collapse-td">
              <flink-job-checkpoints-detail [checkPoint]="checkpoint"></flink-job-checkpoints-detail>
            </td>
          </tr>
        </ng-container>

      </tbody>
    </nz-table>
  </nz-tab>
  <nz-tab nzTitle="Summary">
    <nz-table
      *ngIf="checkPointStats"
      class="no-border small"
      [nzData]="(checkPointStats&&checkPointStats['summary'])?['']:[]"
      [nzSize]="'small'"
      [nzFrontPagination]="false"
      [nzShowPagination]="false">
      <thead>
        <tr>
          <th></th>
          <th><strong>End to End Duration</strong></th>
          <th><strong>Checkpointed Data Size</strong></th>
          <th><strong>Processed (persisted) in-flight data</strong></th>
        </tr>
      </thead>
      <tbody>
        <ng-container *ngIf="checkPointStats['summary']">
          <tr>
            <td><strong>Minimum</strong></td>
            <td>{{ checkPointStats['summary']['end_to_end_duration']['min'] | humanizeDuration}}</td>
            <td>{{ checkPointStats['summary']['state_size']['min'] | humanizeBytes }}</td>
            <td>{{ checkPointStats['summary']['processed_data']['min'] | humanizeBytes }} ({{ checkPointStats['summary']['persisted_data']['min'] | humanizeBytes }})</td>
          </tr>
          <tr>
            <td><strong>Average</strong></td>
            <td>{{ checkPointStats['summary']['end_to_end_duration']['avg'] | humanizeDuration}}</td>
            <td>{{ checkPointStats['summary']['state_size']['avg'] | humanizeBytes }}</td>
            <td>{{ checkPointStats['summary']['processed_data']['avg'] | humanizeBytes }} ({{ checkPointStats['summary']['persisted_data']['avg'] | humanizeBytes }})</td>
          </tr>
          <tr>
            <td><strong>Maximum</strong></td>
            <td>{{ checkPointStats['summary']['end_to_end_duration']['max'] | humanizeDuration}}</td>
            <td>{{ checkPointStats['summary']['state_size']['max'] | humanizeBytes }}</td>
            <td>{{ checkPointStats['summary']['processed_data']['max'] | humanizeBytes }} ({{ checkPointStats['summary']['persisted_data']['max'] | humanizeBytes }})</td>
          </tr>
        </ng-container>
      </tbody>
    </nz-table>
  </nz-tab>
  <nz-tab nzTitle="Configuration">
    <nz-table
      class="no-border small"
      [nzData]="checkPointConfig?['']:[]"
      [nzSize]="'small'"
      [nzFrontPagination]="false"
      [nzShowPagination]="false">
      <thead>
        <tr>
          <th><strong>Option</strong></th>
          <th><strong>Value</strong></th>
        </tr>
      </thead>
      <tbody>
        <ng-container *ngIf="checkPointConfig">
          <tr>
            <td>Checkpointing Mode</td>
            <td *ngIf="checkPointConfig['mode'] == 'exactly_once'">Exactly Once</td>
            <td *ngIf="checkPointConfig['mode'] != 'exactly_once'">At Least Once</td>
          </tr>
          <tr>
            <td>Interval</td>
            <td *ngIf="checkPointConfig['interval'] == '0x7fffffffffffffff'">Periodic checkpoints disabled</td>
            <td *ngIf="checkPointConfig['interval'] != '0x7fffffffffffffff'">{{ checkPointConfig['interval'] | humanizeDuration}}</td>
          </tr>
          <tr>
            <td>Timeout</td>
            <td>{{ checkPointConfig['timeout'] | humanizeDuration}}</td>
          </tr>
          <tr>
            <td>Minimum Pause Between Checkpoints</td>
            <td>{{ checkPointConfig['min_pause'] | humanizeDuration}}</td>
          </tr>
          <tr>
            <td>Maximum Concurrent Checkpoints</td>
            <td>{{ checkPointConfig['max_concurrent'] }}</td>
          </tr>
          <tr>
            <td>Unaligned Checkpoints</td>
            <td>{{ checkPointConfig['unaligned_checkpoints'] ? 'Enabled' : 'Disabled' }}</td>
          </tr>
          <tr *ngIf="checkPointConfig['externalization']">
            <td>Persist Checkpoints Externally</td>
            <td *ngIf="checkPointConfig['externalization']['enabled']">Enabled
              <span *ngIf="checkPointConfig['externalization']['delete_on_cancellation']">(delete on cancellation)</span>
              <span *ngIf="!checkPointConfig['externalization']['delete_on_cancellation']">(retain on cancellation)</span>
            </td>
            <td *ngIf="!checkPointConfig['externalization']['enabled']">Disabled</td>
          </tr>
          <tr>
            <td>Tolerable Failed Checkpoints</td>
            <td>{{ checkPointConfig['tolerable_failed_checkpoints'] }}</td>
          </tr>
        </ng-container>
      </tbody>
    </nz-table>
  </nz-tab>
</nz-tabset>

<ng-template #extraTemplate>
  <button nz-button nzType="primary" class="refresh" nzSize="small" (click)="refresh()"><i nz-icon type="sync"></i>Refresh</button>
</ng-template>

<nz-empty *ngIf="!checkPointStats"></nz-empty>
